home *** CD-ROM | disk | FTP | other *** search
- Path: newsbf02.news.aol.com!not-for-mail
- From: parhelion@aol.com (Parhelion)
- Newsgroups: comp.lang.c
- Subject: Dynamic array source - email if you find useful
- Date: 6 Feb 1996 09:11:14 -0500
- Organization: America Online, Inc. (1-800-827-6364)
- Sender: root@newsbf02.news.aol.com
- Message-ID: <4f7ni2$cge@newsbf02.news.aol.com>
- Reply-To: parhelion@aol.com (Parhelion)
-
- /*************************************************************************
- ******
- dynarray.c Mark Atchison (parhelion@aol.com)
-
- By use of a linked list of row pointers and a linked list of column
- pointers for
- each row, mimics behavior of a two-dimensional array, but is entirely
- dynamic.
- Created as a QuickWin app under MSVC 1.00, but should be portable.
-
- Features: Sparse in nature; only cells referenced w/ PutTableau are
- actually
- stored - GetTableau returns zero for all other
- values.
- Will accept data in any order.
- Does not use contiguous memory.
- Drawbacks: Slower access than static, speed degrades as array size
- increases.
- Consumes more memory than a static array - in x86 architecture,
- a 5x10 static array of floats uses 200 bytes, while a dynamic
- array
- would consume 430 bytes (assuming all elements are
- referenced).
- Usage: Set ARRAYDATATYPE to desired numeric data type (could be
- adapted to
- pointers, with a little imagination)
- Declare a DYANARRAYROW * (Tableau, in the example)
- Call InitTableau to create first row instance
- Place values in array using PutTableau
- Retrieve values from array using GetTableau
- (uninitialzed cells = 0)
- Free all links with FreeTableau
- **************************************************************************
- *****/
- #include <stdlib.h>
- #include <stdio.h>
- #include <malloc.h>
- #include <string.h>
-
- typedef int BOOL;
- #define FALSE 0
- #define TRUE 1
-
- #define ARRAYDATATYPE float
-
- typedef struct tagDynArrayRow DYNARRAYROW;
- typedef struct tagDynArrayCol DYNARRAYCOL;
-
- struct tagDynArrayCol
- {
- int ColIndex;
- ARRAYDATATYPE ArrayValue;
- DYNARRAYCOL *NextCol_ptr;
- };
-
- struct tagDynArrayRow
- {
- int RowIndex;
- DYNARRAYCOL *FirstCol_ptr;
- DYNARRAYROW *NextRow_ptr;
- };
-
- BOOL InitTableau( DYNARRAYROW ** );
- BOOL PutTableau( DYNARRAYROW *, int, int, ARRAYDATATYPE );
- ARRAYDATATYPE GetTableau( DYNARRAYROW *, int, int );
- void FreeTableau( DYNARRAYROW * );
- void FreeColumns( DYNARRAYCOL * );
-
- DYNARRAYROW * GetRow( DYNARRAYROW *, int );
- DYNARRAYCOL * GetCol( DYNARRAYCOL *, int );
-
- int main()
- {
- DYNARRAYROW *Tableau_ptr = NULL;
- int R, C;
- ARRAYDATATYPE ArrValue = 0;
-
- InitTableau ( &Tableau_ptr ); /* initialize
- first row entry */
-
- /* place values in the array */
- for (R = 0; R < 3; R++)
- {
- for (C = 0; C < 3; C++)
- {
- ArrValue++;
- PutTableau( Tableau_ptr, R, C, ArrValue );
- }
- }
-
- /* retrieve and print array values */
- for (R = 0; R < 3; R++)
- {
- for (C = 0; C < 3; C++)
- {
- printf( "\n%d, %d = %f", R, C, GetTableau(
- Tableau_ptr, R, C ) );
- }
- }
-
- FreeTableau ( Tableau_ptr ); /* Free all linked memory
- */
- return (0);
- }
- /*************************************************************************
- ****
- * I n i t T a b l e a u
- *
- **************************************************************************
- ****/
-
- BOOL InitTableau( DYNARRAYROW **Tableau_ptr)
- {
- *Tableau_ptr = (struct tagDynArrayRow *)
- malloc(sizeof(DYNARRAYROW));
- if ( *Tableau_ptr == NULL )
- return ( FALSE ); /*no memory available for
- first row */
- (*Tableau_ptr)->NextRow_ptr = NULL; /*initialize ptr to next
- row */
- (*Tableau_ptr)->FirstCol_ptr = NULL;/*initialize ptr to first
- column */
- return ( TRUE );
- }
- /*************************************************************************
- ****
- * P u t T a b l e a u
- *
- **************************************************************************
- ****/
-
- BOOL PutTableau( DYNARRAYROW *Tableau_ptr, int R, int C, ARRAYDATATYPE
- ArrValue )
- {
-
- DYNARRAYROW *Row_ptr = NULL;
- DYNARRAYROW *NewRow_ptr = NULL;
- DYNARRAYCOL *Col_ptr = NULL;
- DYNARRAYCOL *NewCol_ptr = NULL;
-
- /*get the exact row or the last row in the link */
- Row_ptr = GetRow ( Tableau_ptr, R );
-
- if ( Row_ptr->FirstCol_ptr == NULL )/*create first row, if no row
- existed*/
- {
- Row_ptr->RowIndex = R; /*record the row
- index value */
- Row_ptr->NextRow_ptr = NULL; /*and set next row to NULL
- */
-
- Row_ptr->FirstCol_ptr = (struct tagDynArrayCol *)
- malloc(sizeof(DYNARRAYCOL));
-
- if ( Row_ptr->FirstCol_ptr == NULL )
-
- return ( FALSE ); /*no memory available
- for first col */
-
- Row_ptr->FirstCol_ptr->ColIndex = C;
- Row_ptr->FirstCol_ptr->ArrayValue = ArrValue;
- Row_ptr->FirstCol_ptr->NextCol_ptr = NULL;
- return ( TRUE );
- }
-
- /*determine if requested row was found */
- if ( Row_ptr->RowIndex == R ) /*if this is requested row
- */
- {
- Col_ptr = GetCol ( Row_ptr->FirstCol_ptr, C );
- if ( Col_ptr->ColIndex == C )
- {
- Col_ptr->ArrayValue = ArrValue;
- }
- else
-
- {
- NewCol_ptr = (struct tagDynArrayCol *)
- malloc(sizeof(DYNARRAYCOL));
-
- if ( NewCol_ptr == NULL )
-
- return ( FALSE ); /*no memory
- available for next column*/
-
- Col_ptr->NextCol_ptr = NewCol_ptr;
-
- Col_ptr = NewCol_ptr; /*move to the new column
- */
-
- Col_ptr->ColIndex = C; /*record the column index
- value */
- Col_ptr->NextCol_ptr = NULL;/*and set next column
- to NULL */
- Col_ptr->ArrayValue = ArrValue;
- }
- }
- else
- /*add the row and first column */
- {
- NewRow_ptr = (struct tagDynArrayRow *)
- malloc(sizeof(DYNARRAYROW));
-
- if ( NewRow_ptr == NULL )
- return ( FALSE ); /*no memory available
- for next row */
-
- Row_ptr->NextRow_ptr = NewRow_ptr;
-
- Row_ptr = NewRow_ptr; /*move to the new row
- */
-
- Row_ptr->RowIndex = R; /*record the row index
- value */
- Row_ptr->NextRow_ptr = NULL; /*and set next row to NULL
- */
-
- Row_ptr->FirstCol_ptr = (struct tagDynArrayCol *)
- malloc(sizeof(DYNARRAYCOL));
-
- if ( Row_ptr->FirstCol_ptr == NULL )
-
- return ( FALSE ); /*no memory for first
- col of row */
-
- Row_ptr->FirstCol_ptr->ColIndex = C;
- Row_ptr->FirstCol_ptr->ArrayValue = ArrValue;
- Row_ptr->FirstCol_ptr->NextCol_ptr = NULL;
- }
-
- return( TRUE );
- }
- /*************************************************************************
- ****
- * G e t T a b l e a u
- *
- **************************************************************************
- ****/
-
- ARRAYDATATYPE GetTableau( DYNARRAYROW *Tableau_ptr, int R, int C )
- {
-
- DYNARRAYROW *Row_ptr = NULL;
- DYNARRAYCOL *Col_ptr = NULL;
-
- /*find the exact row requested or return the last row in the list
- */
- Row_ptr = GetRow ( Tableau_ptr, R );
- if ( Row_ptr->RowIndex != R) /*if not exact row
- return 0 */
- return ( 0 );
-
- /*find the column in the row */
- Col_ptr = GetCol ( Row_ptr->FirstCol_ptr, C );
- if ( Col_ptr->ColIndex != C) /*if not exact col return
- 0 */
- return ( 0 );
-
- return ( Col_ptr->ArrayValue );
- }
- /*************************************************************************
- ****
- * G e t R o w
- *
- **************************************************************************
- ****/
-
- DYNARRAYROW * GetRow( DYNARRAYROW *Row_ptr, int R )
- {
- DYNARRAYROW *tmp_ptr = Row_ptr;
-
- while( tmp_ptr->RowIndex != R ) /*return exact row or last
- in list */
- {
- if ( tmp_ptr->NextRow_ptr == NULL )
- return ( tmp_ptr );
- tmp_ptr = tmp_ptr->NextRow_ptr;
- }
- return ( tmp_ptr );
- }
-
- /*************************************************************************
- ****
- * G e t C o l
- *
- **************************************************************************
- ****/
-
- DYNARRAYCOL * GetCol( DYNARRAYCOL *Col_ptr, int C )
- {
- DYNARRAYCOL *tmp_ptr = Col_ptr;
-
- while( tmp_ptr->ColIndex != C ) /*return exact col or last
- in list */
- {
- if ( tmp_ptr->NextCol_ptr == NULL )
- return ( tmp_ptr );
- tmp_ptr = tmp_ptr->NextCol_ptr;
- }
- return ( tmp_ptr );
- }
-
- /*************************************************************************
- ****
- * F r e e T a b l e a u
- *
- **************************************************************************
- ****/
-
- void FreeTableau( DYNARRAYROW *Row_ptr )
- {
- DYNARRAYROW *tmp_ptr;
-
- while ( Row_ptr != NULL )
- {
- FreeColumns ( Row_ptr->FirstCol_ptr );
- tmp_ptr = Row_ptr->NextRow_ptr;
- free ( Row_ptr );
- Row_ptr = tmp_ptr;
- }
- return;
- }
-
- /*************************************************************************
- ****
- * F r e e C o l u m n
- *
- **************************************************************************
- ****/
-
- void FreeColumns( DYNARRAYCOL *Col_ptr )
- {
- DYNARRAYCOL *tmp_ptr;
-
- while ( Col_ptr != NULL )
- {
- tmp_ptr = Col_ptr->NextCol_ptr;
- free ( Col_ptr );
- Col_ptr = tmp_ptr;
- }
- return;
- }
-